package com.songlanyun.modules.order.model.vo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.annotation.ExcelEntity;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.drive.ValueObject;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.common.utils.custom.DateCustomUtils;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.order.entity.ChildOrder;
import com.songlanyun.modules.order.entity.OrderReceipt;
import com.songlanyun.modules.order.entity.OrderSelfTake;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.order.service.OrderReceiptService;
import com.songlanyun.modules.order.service.OrderSelfTakeService;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.rabbitmq.util.SpringContextUtil;
import com.songlanyun.modules.ship.entity.OrderPackage;
import com.songlanyun.modules.ship.service.OrderPackageService;
import com.songlanyun.modules.shop.entity.ShopEntity;
import com.songlanyun.modules.shop.service.ShopService;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 销售系统中的主订单
 *
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2020-11-16 14:14:42
 */
@Data
@ExcelTarget("orderVO")
public class OrderVO implements ValueObject {


    @Excel(name = "订单号", orderNum = "1", width = 15D, needMerge = true)
    private String orderCode;
    /**
     * 聚合支付订单号
     */
    @Excel(name = "支付订单号", orderNum = "2", width = 15D, needMerge = true)
    private String payOrderCode;



    /**
     * 所属店铺名称
     */
    @Excel(name = "店铺名称", orderNum = "3", width = 20D, needMerge = true)
    private String shopName;

    /**
     * 订单来源商家店铺名称
     */
    @Excel(name = "订单来源商家", orderNum = "4", width = 20D, needMerge = true)
    private String sourceShopName;

    /**
     * 支付方式（0余额，1微信，2支付宝）
     * 支付方式（0余额，1微信，2支付宝,3银行线下,4现金支付,5积分支付,6积分+余额支付,7积分+微信支付,8积分+支付宝支付）
     */
    @Excel(name = "支付方式", orderNum = "5", replace = {"余额支付_0", "微信_1", "支付宝_2","银行线下_3","现金支付_4","积分支付_5","积分+余额支付_6","积分+微信支付_7","积分+支付宝支付_8","支付宝汇付_10","积分+支付宝汇付_11"}, width = 10D, needMerge = true)
    private Integer payMode;



    /**
     * 原商品总价
     */
    @Excel(name = "原商品总价", orderNum = "6", width = 10D , needMerge = true)
    private BigDecimal originalGoodsAmount;

    /**
     * 真实的物流费用
     */
    @Excel(name = "运费", orderNum = "7", width = 10D, needMerge = true)
    private BigDecimal realFreight;

    /**
     * 总优惠
     */
    @Excel(name = "总优惠", orderNum = "8", width = 10D, needMerge = true)
    private BigDecimal totalReduced;
    /**
     * 首单优惠多少钱
     */
    @Excel(name = "首单优惠", orderNum = "9", width = 10D, needMerge = true)
    private BigDecimal firstOrderReduced;

    /**
     * 总费用(包含运费)
     */
    @Excel(name = "费用(包含运费)", orderNum = "10", width = 10D, needMerge = true)
    private BigDecimal totalAmount;


    /**
     * 会员手机号
     */
    @Excel(name = "购买会员手机号", orderNum = "11", width = 10D, needMerge = true)
    private String mobile;

    /**
     * 出货方式（0物流，1自提，2预约）
     */
    @Excel(name = "出货方式", orderNum = "12", replace = {"物流_0", "自提_1", "预约_2"}, width = 10D, needMerge = true)
    private Integer shipmentMode;


    /**
     * 是否积分兑换订单
     */
    @Excel(name = "是否积分兑换订单", orderNum = "13", replace = {"是_true", "否_false"}, width = 10D, needMerge = true)
    private Boolean exchange;

    /**
     * 兑换订单使用总积分
     */
    @Excel(name = "使用总积分", orderNum = "14", width = 10D, needMerge = true)
    private Integer totalPoint;


    /**
     * 会员下单时的订单备注
     */
    @Excel(name = "会员单备注", orderNum = "15", width = 20D, needMerge = true)
    private String userRemark;

    /**
     * 0系统自动,1 微信小程序，2 APP（订单来源）
     */
    @Excel(name = "下单渠道", orderNum = "16", replace = {"系统_0", "微信小程序_1","APP_2"}, width = 20D, needMerge = true)
    private Integer channelType;


    /**
     * 营销活动内类型(0无活动，1秒杀，2拼团）
     */
    @Excel(name = "活动类型", orderNum = "16", replace = {"无活动_0", "秒杀_1","拼团_2"}, width = 20D, needMerge = true)
    private Integer marketingType;


    @TableField(exist = false)
    @Excel(name = "订单时间", orderNum = "17", width = 15D, needMerge = true)
    private String formatOrderTime;


    @TableField(exist = false)
    @Excel(name = "支付时间", orderNum = "18", width = 15D, needMerge = true)
    private String formatPayTime;

    /**
     * 主订单交易完成时间
     */
    @Excel(name = "交易完成时间", orderNum = "19", width = 15D, needMerge = true)
    private String formatCompleteTime;

    @TableField(exist = false)
    @Excel(name = "最后发货时间", orderNum = "20", width = 15D, needMerge = true)
    private String formatLastShipTime;

    @TableField(exist = false)
    @Excel(name = "最后收货时间", orderNum = "21", width = 15D, needMerge = true)
    private String formatLastReceiptTime;

    /**
     * 订单类型（0充值 1消费订单，2服务订单）
     */
    @Excel(name = "订单类型", orderNum = "22", replace = {"消费订单_1", "服务订单_2"} ,width = 15D, needMerge = true)
    private Integer orderType;

    /**
     * 交易状态（0已下单,待支付，1待发货（待备货），2,"部分发货",3,"待收货（待自提）"，4,"部分收货",5交易完成,6关闭
     */
    @Excel(name = "交易状态", orderNum = "23", replace = {"已下单,待支付_0", "待发货（待备货)_1","部分发货_2", "待收货（待自提）_3", "部分收货_4", "交易完成_5", "关闭_6"} ,width = 10D, needMerge = true)
    private Integer transactionStatus;

    /**
     * 0用户未评，1用户部分已评，2全部已评
     */
    @Excel(name = "评价类型", orderNum = "24", replace = {"用户未评_0", "用户部分已评_1","全部已评_2"} ,width = 15D, needMerge = true)
    private Integer commentStatus;


    /**
     * 是否关闭（封单也是关闭）
     */
    @Excel(name = "是否关单", orderNum = "25", replace = {"关单_true", "未关单_false"} ,width = 15D, needMerge = true)
    private Boolean end;

    /**
     * 0没有，1仅退款,2退款退货
     */
    @Excel(name = "维权类型", orderNum = "26", replace = {"没有_0","仅退款_1", "退款退货_2"} ,width =8D, needMerge = true)
    private Integer rightsType;
    /**
     * 订单的维权状态（0没有，1维权中，2完成）
     */
    @Excel(name = "维权状态", orderNum = "27", replace = {"没有_0","权中_1", "维权成功_2"} ,width =8D, needMerge = true)
    private Integer rightsStatus;


    /**
     * 0未支付 1支付成功，但业务发生异常需要发起退款 2支付成功，但业务发生异常自款成功 3支付成功，但业务发生异常退款失败 4支付失败 5已支付(已支付成功)
     */
    @Excel(name = "支付状态", orderNum = "28", replace = {"未支付 _0","支付成功，但业务发生异常需要发起退款_1", "支付成功，但业务发生异常自退款成功_2","支付成功，但业务发生异常退款失败_3","支付失败_4","已支付_5","支付过期_6"} ,width =8D, needMerge = true)
    private Integer paymentStatus;





    /**
     * 平台优惠券Id
     */
    private Long platformCouponId = 0L;

    /**
     * 平台优惠券名称
     */
    private String platformCouponName = "无可使用券";

    /**
     * 平台优惠券面额
     */
    private BigDecimal platformCouponFaceValue = BigDecimal.ZERO;

    /**
     * 平台券分摊多少钱
     */
    private BigDecimal platformCouponSharing = BigDecimal.ZERO;


    /**
     * 店铺优惠券Id
     */
    private Long shopCouponId = 0L;

    /**
     * 店铺优惠券名称
     */
    private String shopCouponName = "无可使用券";

    /**
     * 店铺优惠券面额
     */
    private BigDecimal shopCouponFaceValue = BigDecimal.ZERO;

    /**
     * 店铺优惠券实际优惠多少(对于支付订单，店铺订单，实际的商品子订单)
     */
    private BigDecimal shopCouponResultValue = BigDecimal.ZERO;







    /**
     * 订单是否已起效（如团购订单只有团建成才起效，才可以发货）
     */
    private Boolean effective;

    /**
     * 实际商品总费用
     */
    private BigDecimal goodsAmount;
    /**
     *
     */
    private Long id;
    /**
     *
     */
    /**
     * 订单所属店铺id
     */
    private Long shopId;

    /**
     * 订单来源商家店铺id
     */
    private Long sourceShopId;

    /**
     * 是否是代销订单
     */
    private Boolean proxy;
    /**
     * 下单会员
     */
    private Long userId;



    /**
     * 实际计算得到的物流费用(合计)
     */
    private BigDecimal shouldFreight;



    /**
     * 商品总数量
     */
    private Integer goodsNumber;


    /**
     * 会员折扣优惠的费用（如果商品下单改价，也是这个）
     *
     * @return
     */
    public BigDecimal getDiscountAmount() {
        return MathUtils.subtract(originalGoodsAmount, goodsAmount);
    }

    /**
     * 总成本
     */
    private BigDecimal totalCost;

    /**
     * 购物完成赠送积分
     */
    private Integer finalGiveBackPoint;

    /**
     * 商家备注
     */
    private String businessRemark;
    /**
     * 商家为订单设置重要级别(1-5级)
     */
    private Integer importance = 1;
    /**
     * 下单会员所在商家等级编码
     */
    private String userRoleCode;
    /**
     * 下单会员所在商家等级名称
     */
    private String userRoleName;



    /**
     * 支付是否过期
     */
    private Boolean expired = false;
    /**
     * 支付过期时间（时间戳）
     */
    private Long expiredTime;

    public void setExpiredTime(Long expiredTime) {
        this.expiredTime = expiredTime;
        this.formatExpiredTime = DateCustomUtils.formatToDateTimeString(expiredTime);
    }

    @TableField(exist = false)
    private String formatExpiredTime;
    /**
     * 下单时间（时间戳）
     */
    private Long orderTime;

    public void setOrderTime(Long orderTime) {
        this.orderTime = orderTime;
        this.formatOrderTime = DateCustomUtils.formatToDateTimeString(orderTime);
    }


    /**
     * 支付时间(时间戳)
     */
    private Long payTime;

    public void setPayTime(Long payTime) {
        this.payTime = payTime;
        this.formatPayTime = DateCustomUtils.formatToDateTimeString(payTime);
    }

    /**
     * 聚合支付订单id
     */
    /**
     * 会员手机号
     */
    private Long payOrderId;

    private String formatAutoStockUpLastTime;

    /**
     * 最后的发货时间（时间戳）（商家发货时间）
     */
    private Long lastShipTime;

    public void setLastShipTime(Long lastShipTime) {
        this.lastShipTime = lastShipTime;
        this.formatLastShipTime = DateCustomUtils.formatToDateTimeString(lastShipTime);
    }

    /**
     * 最后的收货时间（时间戳）（会员收货时间）
     */
    private Long lastReceiptTime;

    public void setLastReceiptTime(Long lastReceiptTime) {
        this.lastReceiptTime = lastReceiptTime;
        this.formatLastReceiptTime = DateCustomUtils.formatToDateTimeString(lastReceiptTime);
    }


    private Long completeTime;

    public void setCompleteTime(Long completeTime) {
        this.completeTime = completeTime;
        this.formatCompleteTime = DateCustomUtils.formatToDateTimeString(completeTime);
    }

    /**
     * 主订单交易关闭时间(也是封单时间)
     */
    private Long closeTime;

    public void setCloseTime(Long closeTime) {
        this.closeTime = closeTime;
        this.formatCloseTime = DateCustomUtils.formatToDateTimeString(closeTime);
    }

    @TableField(exist = false)
    private String formatCloseTime;

    //活动id
    private Long activityId;
    //活动标题
    private String activityTitle;
    //活动发起信息id(如果是限时折扣和首单优惠活动，其为0，如果是拼团其为发起的团Id
    private Long sponsorActivityId = 0L;

    /**
     * 0未关闭,1用户撤销关闭,2商家撤销关闭,3支付过期关闭,4退货成功,5退款成功,6支付成功,但条件已经不允许购买,发生自动退款关闭,7自提过期
     */
    private OrderConstant.CloseMode closeMode;
    /**
     * 0未发货，1部分发货，2已发货
     */
    private OrderConstant.ShipStatus shipStatus;
    /**
     * 0，未收货，1部分收货，2已收货
     */
    private OrderConstant.ReceiptStatus receiptStatus;


    private Date createTime;
    /**
     *
     */
    private Date updateTime;

    /**
     * 主订单下面的子订单
     */
    @ExcelCollection(name = "子订单", orderNum = "37")
    private List<ChildOrderVO> childOrderList;

    public List<ChildOrderVO> getChildOrderList(boolean load) {
        if (load || childOrderList == null) {
            ChildOrderService childOrderService = (ChildOrderService) SpringContextUtil.getBean("childOrderService");
            childOrderList = childOrderService.vosByOrderId(this.getId());
        }
        return childOrderList;
    }

    /**
     * 订单的收件人信息
     */
    @ExcelEntity(id="OrderReceiptVO")
    private OrderReceiptVO receipt;

    /**
     * 订单的自提人信息
     */
    @ExcelEntity(id="OrderSelfTakeVO")
    private OrderSelfTakeVO selfTake;



    /**
     * 订单的自提人信息
     */
    @ExcelEntity(id="SaleServiceOrderContactsVO")
    private SaleServiceOrderContactsVO contactsVO;




}
